package org.msn.server.database.impl;

import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.msn.config.RoomInfo;
import org.msn.server.database.CreateDatabaseLink;
import org.msn.server.database.Repository;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Slf4j
public class MemoryRepositoryImpl extends CreateDatabaseLink<Map<String, RoomInfo>> implements Repository {
    public MemoryRepositoryImpl(String type, Map<String, Object> info) {
        super(type, info);
    }

    @Override
    protected Map<String, RoomInfo> createDatabaseLink(Map<String, Object> info) {
        return new ConcurrentHashMap<>();
    }

    @Override
    public List<ChannelHandlerContext> getAllRoomUser(String roomName) {
        return getDatabaseLink().get(roomName).getMap().keySet().stream().collect(Collectors.toList());
    }

    @Override
    public List<RoomInfo> getAllRoom() {
        List<RoomInfo> list = new ArrayList<>();
        getDatabaseLink().forEach((k, v) -> {
            list.add(v);
        });
        return list;
    }

    @Override
    public boolean addRoomInfo(RoomInfo roomInfo) {
        try {
            getDatabaseLink().put(roomInfo.getName(), roomInfo);
            return true;
        } catch (Exception e) {
            log.info(e.getMessage());
            return false;
        }
    }

    @Override
    public boolean addUserToRoom(ChannelHandlerContext ctx, String username, String name) {
        try {
            getDatabaseLink().get(name).getMap().put(ctx, username);
            return true;
        } catch (Exception e) {
            log.info(e.getMessage());
            return false;
        }
    }

    @Override
    public RoomInfo getRoomByName(String roomName) {
        return getDatabaseLink().get(roomName);
    }

    @Override
    public Integer getRoomAllUserByName(String roomName) {
        AtomicInteger size = new AtomicInteger(0);
        getDatabaseLink().get(roomName).getMap().forEach((k, v) -> {
            size.incrementAndGet();
        });
        return size.get();
    }

    @Override
    public boolean removeUserFromRoom(String roomName, ChannelHandlerContext ctx) {
        try {
            getDatabaseLink().get(roomName).getMap().remove(ctx);
            return true;
        } catch (Exception e) {
            log.info(e.getMessage());
            return false;
        }
    }

    @Override
    public boolean removeRoomByName(String roomName) {
        try {
            getDatabaseLink().remove(roomName);
            return true;
        } catch (Exception e) {
            log.info(e.getMessage());
            return false;
        }
    }

    @Override
    public List<ChannelHandlerContext> getRoomAllUserIPByName(String name) {
        return getDatabaseLink().get(name).getMap().keySet().stream().collect(Collectors.toList());
    }

    @Override
    public List<String> getAllRoomName() {
        List<String> list = new ArrayList<>();
        getDatabaseLink().forEach((k, v) -> {
            list.add(v.getName());
        });
        return list;
    }
}
